home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / radius_2.zip / users.c < prev    next >
C/C++ Source or Header  |  1996-05-28  |  12KB  |  560 lines

  1. /*
  2.  *
  3.  *    RADIUS
  4.  *    Remote Authentication Dial In User Service
  5.  *
  6.  *
  7.  *    Livingston Enterprises, Inc.
  8.  *    6920 Koll Center Parkway
  9.  *    Pleasanton, CA   94566
  10.  *
  11.  *    Copyright 1992 Livingston Enterprises, Inc.
  12.  *
  13.  *    Permission to use, copy, modify, and distribute this software for any
  14.  *    purpose and without fee is hereby granted, provided that this
  15.  *    copyright and permission notice appear on all copies and supporting
  16.  *    documentation, the name of Livingston Enterprises, Inc. not be used
  17.  *    in advertising or publicity pertaining to distribution of the
  18.  *    program without specific prior permission, and notice be given
  19.  *    in supporting documentation that copying and distribution is by
  20.  *    permission of Livingston Enterprises, Inc.   
  21.  *
  22.  *    Livingston Enterprises, Inc. makes no representations about
  23.  *    the suitability of this software for any purpose.  It is
  24.  *    provided "as is" without express or implied warranty.
  25.  *
  26.  */
  27.  
  28. static char sccsid[] =
  29. "@(#)users.c    1.12 Copyright 1992 Livingston Enterprises Inc";
  30.  
  31. #include    <sys/types.h>
  32. #include    <sys/socket.h>
  33. #include    <sys/time.h>
  34. #include    <netinet/in.h>
  35.  
  36. #include    <stdio.h>
  37. #include    <stdlib.h>
  38. #include    <netdb.h>
  39. #include    <pwd.h>
  40. #include    <time.h>
  41. #include    <ctype.h>
  42. #include    "radius.h"
  43.  
  44. #ifdef DBM
  45.  
  46. #include    <dbm.h>
  47.  
  48. #endif /* DBM */
  49.  
  50.  
  51. extern char        *progname;
  52. extern int        debug_flag;
  53. extern char        *radius_dir;
  54.  
  55. static    void fieldcpy();
  56. static    int  userparse();
  57.  
  58. #define FIND_MODE_NAME    0
  59. #define FIND_MODE_REPLY    1
  60. #define FIND_MODE_SKIP    2
  61. #define FIND_MODE_FLUSH    3
  62.  
  63. void user_gettime(char        *valstr,struct tm    *tm);
  64.  
  65. /*************************************************************************
  66.  *
  67.  *    Function: user_find
  68.  *
  69.  *    Purpose: Find the named user in the database.  Create the
  70.  *         set of attribute-value pairs to check and reply with
  71.  *         for this user from the database.
  72.  *
  73.  *************************************************************************/
  74. int
  75. user_find(name, check_pairs, reply_pairs)
  76. char    *name;
  77. VALUE_PAIR    **check_pairs;
  78. VALUE_PAIR    **reply_pairs;
  79. {
  80.     FILE        *userfd;
  81.     char        buffer[256];
  82.     char        msg[128];
  83.     char        *ptr;
  84.     int        namelen;
  85.     int        mode;
  86.     VALUE_PAIR    *check_first;
  87.     VALUE_PAIR    *reply_first;
  88. #ifdef DBM
  89.     datum        named;
  90.     datum        contentd;
  91. #endif /* DBM */
  92.  
  93.     /* 
  94.      * Check for valid input, zero length names not permitted 
  95.      */
  96.     userfd = NULL;
  97.     mode = FIND_MODE_NAME;
  98.  
  99.     ptr=name;
  100.     while (*ptr != '\0') {
  101.         if (*ptr == ' ' || *ptr == '\t') {
  102.             *ptr = '\0';
  103.         } else {
  104.             ptr++;
  105.         }
  106.     }
  107.  
  108.     namelen=strlen(name);
  109.  
  110.     if (namelen < 1) {
  111.         fprintf(stderr, "%s: zero length username not permitted\n",progname);
  112.         return(-1);
  113.     }
  114.  
  115.  
  116.     /*
  117.      * Open the user table
  118.      */
  119.     sprintf(buffer, "%s/%s", radius_dir, RADIUS_USERS);
  120. #ifdef DBM
  121.     if(dbminit(buffer) != 0) {
  122. #else /* DBM */
  123.     if((userfd = fopen(buffer, "r")) == (FILE *)NULL) {
  124. #endif /* DBM */
  125.         fprintf(stderr, "%s:Couldn't open %s for reading\n",
  126.                 progname, buffer);
  127.         return(-1);
  128.     }
  129.  
  130.     check_first = (VALUE_PAIR *)NULL;
  131.     reply_first = (VALUE_PAIR *)NULL;
  132.  
  133.  
  134. #ifdef DBM
  135.     named.dptr = name;
  136.     named.dsize = strlen(name);
  137.     contentd = fetch(named);
  138.  
  139.     if(contentd.dsize == 0) {
  140.         named.dptr = "DEFAULT";
  141.         named.dsize = strlen("DEFAULT");
  142.         contentd = fetch(named);
  143.         if(contentd.dsize == 0) {
  144.             dbmclose();
  145.             return(-1);
  146.         }
  147.     }
  148.  
  149.     /*
  150.      * Parse the check values
  151.      */
  152.     ptr = contentd.dptr;
  153.     contentd.dptr[contentd.dsize] = '\0';
  154.  
  155.     if(userparse(ptr, &check_first) != 0) {
  156.         sprintf(msg, "%s: Parse error for user %s\n",
  157.                 progname, name);
  158.         fprintf(stderr, msg);
  159.         log_err(msg);
  160.         pairfree(check_first);
  161.         dbmclose();
  162.         return(-1);
  163.     }
  164.     while(*ptr != '\n' && *ptr != '\0') {
  165.         ptr++;
  166.     }
  167.     if(*ptr != '\n') {
  168.         pairfree(check_first);
  169.         dbmclose();
  170.         return(-1);
  171.     }
  172.     ptr++;
  173.     /*
  174.      * Parse the reply values
  175.      */
  176.     if(userparse(ptr, &reply_first) != 0) {
  177.         fprintf(stderr, "%s: Parse error for user %s\n",
  178.             progname, name);
  179.         pairfree(check_first);
  180.         pairfree(reply_first);
  181.         dbmclose();
  182.         return(-1);
  183.     }
  184.     dbmclose();
  185.  
  186. #else /* DBM */
  187.  
  188.     while(fgets(buffer, sizeof(buffer), userfd) != (char *)NULL) {
  189.         if(mode == FIND_MODE_NAME) {
  190.             /*
  191.              * Find the entry starting with the users name
  192.              */
  193.             if((strncmp(buffer, name, namelen) == 0 &&
  194.               (buffer[namelen] == ' ' || buffer[namelen] == '\t')) ||
  195.                      strncmp(buffer, "DEFAULT", 7) == 0) {
  196.                 if(strncmp(buffer, "DEFAULT", 7) == 0) {
  197.                     ptr = &buffer[7];
  198.                 }
  199.                 else {
  200.                     ptr = &buffer[namelen];
  201.                 }
  202.                 /*
  203.                  * Parse the check values
  204.                  */
  205.                 if(userparse(ptr, &check_first) != 0) {
  206.                     sprintf(msg,"%s: Parse error for user %s\n",
  207.                         progname, name);
  208.                     fprintf(stderr,msg);
  209.                     log_err(msg);
  210.                     pairfree(check_first);
  211.                     fclose(userfd);
  212.                     return(-1);
  213.                 }
  214.                 mode = FIND_MODE_REPLY;
  215.             }
  216.         }
  217.         else {
  218.             if(*buffer == ' ' || *buffer == '\t') {
  219.                 /*
  220.                  * Parse the reply values
  221.                  */
  222.                 if(userparse(buffer, &reply_first) != 0) {
  223.                     fprintf(stderr,
  224.                         "%s: Parse error for user %s\n",
  225.                         progname, name);
  226.                     pairfree(check_first);
  227.                     pairfree(reply_first);
  228.                     fclose(userfd);
  229.                     return(-1);
  230.                 }
  231.             }
  232.             else {
  233.                 /* We are done */
  234.                 fclose(userfd);
  235.                 *check_pairs = check_first;
  236.                 *reply_pairs = reply_first;
  237.                 return(0);
  238.             }
  239.         }
  240.     }
  241.     fclose(userfd);
  242. #endif /* DBM */
  243.  
  244.     /* Update the callers pointers */
  245.     if(reply_first != (VALUE_PAIR *)NULL) {
  246.         *check_pairs = check_first;
  247.         *reply_pairs = reply_first;
  248.         return(0);
  249.     }
  250.     return(-1);
  251. }
  252.  
  253. #define PARSE_MODE_NAME        0
  254. #define PARSE_MODE_EQUAL    1
  255. #define PARSE_MODE_VALUE    2
  256. #define PARSE_MODE_INVALID    3
  257.  
  258. /*************************************************************************
  259.  *
  260.  *    Function: userparse
  261.  *
  262.  *    Purpose: Parses the buffer to extract the attribute-value pairs.
  263.  *
  264.  *************************************************************************/
  265.  
  266. static int
  267. userparse(buffer, first_pair)
  268. char        *buffer;
  269. VALUE_PAIR    **first_pair;
  270. {
  271.     int        mode;
  272.     char        attrstr[64];
  273.     char        valstr[64];
  274.     DICT_ATTR    *attr;
  275.     DICT_ATTR    *dict_attrfind();
  276.     DICT_VALUE    *dval;
  277.     DICT_VALUE    *dict_valfind();
  278.     VALUE_PAIR    *pair;
  279.     VALUE_PAIR    *link;
  280.     UINT4        ipstr2long();
  281.     UINT4        get_ipaddr();
  282.     struct tm    *tm;
  283.     time_t        timeval;
  284.  
  285.     mode = PARSE_MODE_NAME;
  286.     while(*buffer != '\n' && *buffer != '\0') {
  287.  
  288.         if(*buffer == ' ' || *buffer == '\t' || *buffer == ',') {
  289.             buffer++;
  290.             continue;
  291.         }
  292.  
  293.         switch(mode) {
  294.  
  295.         case PARSE_MODE_NAME:
  296.             /* Attribute Name */
  297.             fieldcpy(attrstr, &buffer);
  298.             if((attr = dict_attrfind(attrstr)) ==
  299.                         (DICT_ATTR *)NULL) {
  300.                 return(-1);
  301.             }
  302.             mode = PARSE_MODE_EQUAL;
  303.             break;
  304.  
  305.         case PARSE_MODE_EQUAL:
  306.             /* Equal sign */
  307.             if(*buffer == '=') {
  308.                 mode = PARSE_MODE_VALUE;
  309.                 buffer++;
  310.             }
  311.             else {
  312.                 return(-1);
  313.             }
  314.             break;
  315.  
  316.         case PARSE_MODE_VALUE:
  317.             /* Value */
  318.             fieldcpy(valstr, &buffer);
  319.  
  320.             if((pair = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) ==
  321.                         (VALUE_PAIR *)NULL) {
  322.                 fprintf(stderr, "%s: no memory\n",
  323.                         progname);
  324.                 exit(-1);
  325.             }
  326.             strcpy(pair->name, attr->name);
  327.             pair->attribute = attr->value;
  328.             pair->type = attr->type;
  329.  
  330.             switch(pair->type) {
  331.  
  332.             case PW_TYPE_STRING:
  333.                 strcpy(pair->strvalue, valstr);
  334.                 break;
  335.  
  336.             case PW_TYPE_INTEGER:
  337.                 if(isdigit(*valstr)) {
  338.                     pair->lvalue = atoi(valstr);
  339.                 }
  340.                 else if((dval = dict_valfind(valstr)) ==
  341.                             (DICT_VALUE *)NULL) {
  342.                     free(pair);
  343.                     return(-1);
  344.                 }
  345.                 else {
  346.                     pair->lvalue = dval->value;
  347.                 }
  348.                 break;
  349.  
  350.             case PW_TYPE_IPADDR:
  351.                 pair->lvalue = get_ipaddr(valstr);
  352.                 break;
  353.  
  354.             case PW_TYPE_DATE:
  355.                 timeval = time(0);
  356.                 tm = localtime(&timeval);
  357.                 user_gettime(valstr, tm);
  358. #ifdef TIMELOCAL
  359.                 pair->lvalue = (UINT4)timelocal(tm);
  360. #else /* TIMELOCAL */
  361.                 pair->lvalue = (UINT4)mktime(tm);
  362. #endif /* TIMELOCAL */
  363.                 break;
  364.  
  365.             default:
  366.                 free(pair);
  367.                 return(-1);
  368.             }
  369.             pair->next = (VALUE_PAIR *)NULL;
  370.             if(*first_pair == (VALUE_PAIR *)NULL) {
  371.                 *first_pair = pair;
  372.             }
  373.             else {
  374.                 link = *f